﻿Imports System.Net
Imports System.Text
Imports System.Xml
Imports System.IO
Imports System.Data


Public Class Freshmobile
    Dim fbDS As New fbXml
    Dim fbChangeOptions As Boolean = False

    Public Sub LoadFreshMobile() Handles Me.Load
        LandscapeModeFix()
        SetHours()
        menuGetData.Text = "Get FreshBooks Data"
    End Sub
    Public Sub SetHours()
        Dim BillInc As Double = 0
        Dim fbBillingInc As Double = CDbl(Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbBillingInc", ""))
        If fbBillingInc = Nothing Then fbBillingInc = 0.5
        timeHours.Items.Clear()
        While BillInc < 12
            BillInc = BillInc + fbBillingInc
            timeHours.Items.Add(BillInc)
        End While
    End Sub
    Private Sub LandscapeModeFix() Handles Me.Resize
        timeProject.Width = ClientSize.Width - (2 * timeProject.Left)
        timeTask.Width = ClientSize.Width - (2 * timeTask.Left)
        timeNotes.Width = ClientSize.Width - (2 * timeNotes.Left)
        If ClientSize.Width > 205 Then
            timeDate.Width = 115
        Else
            timeDate.Width = 68
        End If
    End Sub
    Private Sub SetControlData()
        ' Populate Time controls
        timeProject.DisplayMember = "name"
        timeProject.ValueMember = "project_id"
        timeProject.DataSource = fbDS.Tables("project")

        timeTask.DisplayMember = "name"
        timeTask.ValueMember = "task_id"
        timeTask.DataSource = fbDS.Tables("task")

        ' Set Other controls and datagrid filters
        frmInvoices.dgInvoices.DataSource = fbDS.Tables("invoice")
        Dim tsInvoice As New DataGridTableStyle()
        tsInvoice.MappingName = "invoice"
        frmInvoices.dgInvoices.TableStyles.Add(tsInvoice)
        frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles.Remove(frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles("invoice_id"))
        'frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles.Remove(frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles("client_id"))
        frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles.Remove(frmInvoices.dgInvoices.TableStyles("invoice").GridColumnStyles("invoices_id"))

        frmClients.dgClients.DataSource = fbDS.Tables("client")
        Dim tsClient As New DataGridTableStyle()
        tsClient.MappingName = "client"
        frmClients.dgClients.TableStyles.Add(tsClient)
        'frmClients.dgClients.TableStyles("client").GridColumnStyles.Remove(frmClients.dgClients.TableStyles("client").GridColumnStyles("client_id"))
        frmClients.dgClients.TableStyles("client").GridColumnStyles.Remove(frmClients.dgClients.TableStyles("client").GridColumnStyles("username"))
        frmClients.dgClients.TableStyles("client").GridColumnStyles.Remove(frmClients.dgClients.TableStyles("client").GridColumnStyles("clients_id"))

        frmPayments.dgPayments.DataSource = fbDS.Tables("payment")
        Dim tsPayments As New DataGridTableStyle()
        tsPayments.MappingName = "payment"
        frmPayments.dgPayments.TableStyles.Add(tsPayments)
        frmPayments.dgPayments.TableStyles("payment").GridColumnStyles.Remove(frmPayments.dgPayments.TableStyles("payment").GridColumnStyles("payment_id"))
        frmPayments.dgPayments.TableStyles("payment").GridColumnStyles.Remove(frmPayments.dgPayments.TableStyles("payment").GridColumnStyles("payments_id"))

        frmTimeEntry.dgTime.DataSource = fbDS.Tables("time_entry")
        Dim tsTime_Entry As New DataGridTableStyle()
        tsTime_Entry.MappingName = "time_entry"
        frmTimeEntry.dgTime.TableStyles.Add(tsTime_Entry)
        frmTimeEntry.dgTime.TableStyles("time_entry").GridColumnStyles.Remove(frmTimeEntry.dgTime.TableStyles("time_entry").GridColumnStyles("time_entry_id"))
        frmTimeEntry.dgTime.TableStyles("time_entry").GridColumnStyles.Remove(frmTimeEntry.dgTime.TableStyles("time_entry").GridColumnStyles("time_entries_id"))

    End Sub
    Public Sub fbSubmitTime(ByVal teProject, ByVal teTask, ByVal teDate, ByVal teHours, ByVal teNotes)
        Dim postData As String = "<?xml version=""1.0"" encoding=""utf-8""?><request method=""time_entry.create""><time_entry><project_id>" & teProject & "</project_id><task_id>" & teTask & "</task_id><hours>" & teHours & "</hours><notes>" & teNotes & "</notes><date>" & teDate & "</date></time_entry></request>"
        fbSubmit(postData)

        timeNotes.Text = ""
        timeStart.Visible = False
        lblTimerStart.Text = "Start"
        lblTimerEnd.Enabled = False

        timeProject.Focus()
    End Sub

    Public Function fbSubmitClient(ByVal txtFirstName, ByVal txtLastName, ByVal txtCompany, ByVal txtEmail, ByVal txtWork, ByVal txtMobile, ByVal txtNotes)
        Dim postData As String = "<?xml version=""1.0"" encoding=""utf-8""?><request method=""client.create""><client><first_name>" & txtFirstName & "</first_name><last_name>" & txtLastName & "</last_name><organization>" & txtCompany & "</organization><email>" & txtEmail & "</email><work_phone>" & txtWork & "</work_phone><mobile>" & txtMobile & "</mobile><notes>" & txtNotes & "</notes></client></request>"
        Return fbSubmit(postData)
    End Function

    Public Function fbSubmit(ByVal postdata As String)
        Cursor.Current = Cursors.WaitCursor
        Dim fbUrl As String = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbUrl", "")
        Dim fbToken As String = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbToken", "")
        Dim reader As XmlTextReader = Nothing
        Dim response As HttpWebResponse = Nothing
        Dim request As HttpWebRequest = Nothing

        Dim fbApiUrl As String = "https://" & fbUrl & "/api/2.1/xml-in"

        'Set data and encode for http post
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postdata)

        'Set Credentials Cache
        Dim myCred As New NetworkCredential(fbToken, "foo", "")
        Dim credCache As New CredentialCache()
        credCache.Add(New Uri("https://" & fbUrl), "Basic", myCred)

        'Create webrequest
        request = DirectCast(WebRequest.Create(fbApiUrl), HttpWebRequest)
        request.Credentials = credCache
        request.UserAgent = "FreshMobile 1.0"
        request.Method = "POST"
        request.ContentType = "application/xml"
        request.ContentLength = byteArray.Length
        request.AllowWriteStreamBuffering = True
        request.PreAuthenticate = True
        request.Timeout = 10000
        request.KeepAlive = False
        request.Proxy = System.Net.GlobalProxySelection.GetEmptyWebProxy()

        Try
            'GetStream and Encode PostData
            Dim dataStream As Stream = request.GetRequestStream()
            dataStream.Write(byteArray, 0, byteArray.Length)
            dataStream.Close()

            ' Set Response
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            Dim receiveStream As Stream = response.GetResponseStream()
            Dim readStream As New StreamReader(receiveStream, Encoding.UTF8)

            Dim ds As New DataSet
            ds.ReadXml(readStream)

            If Not ds.Tables("response").Rows(0)("status") = "ok" Then Throw New Exception("Freshbooks API Update Error:" & vbCrLf & ds.Tables("response").Rows(0)("error"))

            receiveStream.Close()
            readStream.Close()
            response.Close()
            request = Nothing

            Cursor.Current = Cursors.Default

            MsgBox("Data Submitted to Freshbooks Succesfully", MsgBoxStyle.Information, "Data Submitted")


            Dim ErrorSubmit As Integer = 0
            Return ErrorSubmit
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ErrorToString, MsgBoxStyle.Exclamation, "Data Submit Error")
            Dim ErrorSubmit As Integer = 1
            Return ErrorSubmit
        Finally

        End Try
    End Function
    Public Function fbGetData(ByVal fbMethod As String, ByVal fbTable As String) As DataTable
        Cursor.Current = Cursors.WaitCursor
        Dim fbUrl As String = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbUrl", "freshbooksmobile.freshbooks.com")
        Dim fbToken As String = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbToken", "123")
        Dim reader As XmlTextReader = Nothing
        Dim response As HttpWebResponse = Nothing
        Dim request As HttpWebRequest = Nothing

        Dim fbApiUrl As String = "https://" & fbUrl & "/api/2.1/xml-in"
        Dim postData As String = "<?xml version=""1.0"" encoding=""utf-8""?><request method=""" & fbMethod & """><per_page>50</per_page></request>"
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)

        ' Set Credentials Cache
        Dim myCred As New NetworkCredential(fbToken, "foo", "")
        Dim credCache As New CredentialCache()
        credCache.Add(New Uri("https://" & fbUrl), "Basic", myCred)

        request = DirectCast(WebRequest.Create(fbApiUrl), HttpWebRequest)
        request.Credentials = credCache
        request.UserAgent = "FreshMobile 1.0"
        request.Method = "POST"
        request.ContentType = "application/xml"
        request.ContentLength = byteArray.Length
        request.AllowWriteStreamBuffering = True
        request.PreAuthenticate = True
        request.Timeout = 10000
        request.KeepAlive = True
        request.Proxy = System.Net.GlobalProxySelection.GetEmptyWebProxy()

        Try

            'GetStream and Encode PostData
            Dim dataStream As Stream = request.GetRequestStream()
            dataStream.Write(byteArray, 0, byteArray.Length)
            dataStream.Close()


            ' Set Response
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            Dim receiveStream As Stream = response.GetResponseStream()
            Dim readStream As New StreamReader(receiveStream, Encoding.UTF8)

            'Create new dataset and load xml from stream
            Dim ds As New DataSet
            ds.ReadXml(readStream)

            If Not ds.Tables("response").Rows(0)("status") = "ok" Then Throw New Exception("Freshbooks API Update Error:" & vbCrLf & ds.Tables("response").Rows(0)("error"))

            'close connections
            receiveStream.Close()
            readStream.Close()
            response.Close()

            Return ds.Tables(fbTable)
            ds = Nothing

        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ErrorToString, MsgBoxStyle.Exclamation, "Data Request Error")
            request = Nothing
            Return Nothing
        End Try
    End Function
    Public Sub fbDataSet()
        Try
            fbDS.Merge(fbGetData("client.list", "client"), True, MissingSchemaAction.Add)

            fbDS.Merge(fbGetData("project.list", "project"), True, MissingSchemaAction.Add)

            fbDS.Merge(fbGetData("task.list", "task"), True, MissingSchemaAction.Add)

            fbDS.Merge(fbGetData("invoice.list", "invoice"), True, MissingSchemaAction.Add)

            fbDS.Merge(fbGetData("time_entry.list", "time_entry"), True, MissingSchemaAction.Add)

            fbDS.Merge(fbGetData("payment.list", "payment"), True, MissingSchemaAction.Add)

            fbChangeOptions = True
        Catch ex As Exception

        End Try
        'Build data table

    End Sub
    Public Sub menuGetData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuGetData.Click
        If menuGetData.Text = "Get FreshBooks Data" Then
            ' Show Options menu if fbUrl is not defined
            If Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbUrl", "") = "" Then
                frmOptions.Show()
            Else
                Cursor.Current = Cursors.WaitCursor

                fbDataSet()
                If fbChangeOptions = True Then
                    SetControlData()
                    menuGetData.Text = "Submit Time"
                    fbChangeOptions = False
                End If

                Cursor.Current = Cursors.Default


            End If
        Else
            If menuGetData.Text = "Submit Time" Then
                Dim fbDateString As String = timeDate.Value.ToString("s")
                fbDateString = fbDateString.Substring(0, 10)
                fbSubmitTime(timeProject.SelectedValue, timeTask.SelectedValue, fbDateString, timeHours.SelectedItem, timeNotes.Text)
            End If
        End If
    End Sub
    Private Sub menuOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuOptions.Click
        frmOptions.Show()
    End Sub
    Private Sub menuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuExit.Click
        Close()
    End Sub
    Private Sub timerStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblTimerStart.Click
        timeStart.Value = Date.Now
        lblTimerEnd.Visible = True
        lblTimerStart.Visible = False
        timeHours.Enabled = False
        timeHours.SelectedIndex = 0
        lblTimer.Visible = True
        Timer1.Enabled = True
    End Sub

    Private Sub timerEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblTimerEnd.Click
        Timer1.Enabled = False
        Dim timeEnd As Date = Date.Now
        Dim timerHours As TimeSpan
        timerHours = timeEnd.Subtract(timeStart.Value)
        timerSetHours(timerHours)

        lblTimer.Visible = False
        lblTimerEnd.Visible = False
        lblTimerStart.Visible = True
        timeHours.Enabled = True
        timeNotes.Text = "[" & timeStart.Value.ToString("hh:mmtt") & " - " & timeEnd.ToString("hh:mmtt") & "]: " & vbCrLf & timeNotes.Text
        timeNotes.Focus()
    End Sub

    Private Sub timerSetHours(ByVal timerHours As TimeSpan)
        Dim fbBillingInc As Double = CDbl(Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\FreshMobile\", "fbBillingInc", ""))
        If fbBillingInc = Nothing Then fbBillingInc = 0.5
        Dim BillInc As Double = fbBillingInc
        While BillInc < timerHours.TotalHours
            BillInc = BillInc + fbBillingInc
        End While
        timeHours.SelectedIndex = (BillInc / fbBillingInc) - 1
    End Sub

    Private Sub MenuClients_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuClients.Click
        frmClients.Show()
    End Sub

    Private Sub menuRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click

    End Sub

    Private Sub menuInvoices_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuInvoices.Click
        frmInvoices.Show()
    End Sub
    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub

    Private Sub timeProject_OnFocus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timeProject.GotFocus
        AutoScrollPosition = New Point(1, 1)
    End Sub

    Private Sub timeDate_OnFocus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timeDate.GotFocus
        AutoScrollPosition = New Point(1, 1)
    End Sub

    Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
        frmPayments.Show()
    End Sub

    Private Sub MenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem3.Click
        frmTimeEntry.Show()
    End Sub


    Private Sub menuAddClient_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuAddClient.Click
        frmAddClient.Show()

    End Sub

    Private Sub timeDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timeDate.ValueChanged

    End Sub

    Private Sub Timer1_Tick() Handles Timer1.Tick
        Timer1.Interval = 60000
        Dim timeNow As Date = Date.Now
        Dim ts As TimeSpan
        ts = timeNow.Subtract(timeStart.Value)
        Dim elapsedTime As String = String.Format("{0:00}:{1:00}", ts.Hours, ts.Minutes)
        lblTimer.Text = elapsedTime
        timerSetHours(ts)
    End Sub

End Class

